package cn.stylefeng.guns.schedule;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpUtil;
import cn.stylefeng.guns.base.utils.StringUtil;
import cn.stylefeng.guns.modular.common.service.CommonService;
import cn.stylefeng.guns.wechat.WeChatMsgSend;
import cn.stylefeng.guns.wechat.WeChatUrlData;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Maps;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.antlr.v4.runtime.tree.Tree;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;

import static cn.stylefeng.guns.base.consts.ConfigConstant.*;

@Component
@Slf4j
public class Ao81Schedule {
    @Autowired
    private CommonService commonService;
    final static Integer ISSUE = 91570;
    final static Date DATE_INIT = DateUtil.parseDate("2022-11-23");
    static Integer FLAG = 1;


    //    @Scheduled(fixedRate = 60000)
    public void execute() throws IOException {
        DateTime dateTime = DateUtil.offsetDay(new Date(), -1);
        DateTime dateTime2 = DateUtil.offsetDay(new Date(), -2);
        String date = DateUtil.format(dateTime, "yyyy-MM-dd");
        String date2 = DateUtil.format(dateTime2, "yyyy-MM-dd");
        if (DATE_LIST.contains(date) && DATE_LIST.contains(date2)) {
            log.info("{}、{}已有数据，跳过", date, date2);
            return;
        }
        HashBasedTable<String, String, StringBuffer> table = getCodes(date, 1);
        HashBasedTable<String, String, StringBuffer> table2 = getCodes(date2, 1);
        TABLE.putAll(table);
        TABLE.putAll(table2);
        DATE_LIST.clear();
        DATE_LIST.add(date);
        DATE_LIST.add(date2);
    }

    //    @Scheduled(fixedRate = 60000)
    public void execute2() {
        String date = DateUtil.format(new Date(), "yyyy-MM-dd");
        String mm = DateUtil.format(new Date(), "mm");
        log.info("00000000000000:{}", mm.substring(1));
        if (!Arrays.asList("4", "9").contains(mm.substring(1))) {
            return;
        }
        log.info("-----------");
        ThreadUtil.sleep(10000);
        log.info("---++++++++");

        DateTime dateTime1 = DateUtil.offsetDay(new Date(), -1);
        DateTime dateTime2 = DateUtil.offsetDay(new Date(), -2);
        String date1 = DateUtil.format(dateTime1, "yyyy-MM-dd");
        String date2 = DateUtil.format(dateTime2, "yyyy-MM-dd");

        HashBasedTable<String, String, StringBuffer> table = getCodes(date, 1);
        String num = null;
        for (int i = 0; i < 8; i++) {
            Map<String, StringBuffer> row = table.row(date + "-" + i);
            Set<String> nums = row.keySet();
            List<String> list = Lists.newArrayList();
            list.addAll(nums);
            num = list.get(nums.size() - 1);
            String yesCode1 = TABLE.get(date1 + "-" + i, num).toString();
            String yesCode2 = TABLE.get(date2 + "-" + i, num).toString();
            String nowCode = table.get(date + "-" + i, num).toString();
            String msg = StrUtil.format("{}\t{}\t{}\t{}", num, yesCode1, yesCode2, nowCode);
            System.out.println(msg);
            warn(Integer.valueOf(yesCode1), Integer.valueOf(yesCode2), Integer.valueOf(nowCode), num, i);

//            String yesNextCode1 = TABLE.get(date1 + "-" + i, Integer.valueOf(num) + 1 + "").toString();
//            String yesNextCode2 = TABLE.get(date2 + "-" + i, Integer.valueOf(num) + 1 + "").toString();
//            warn2(Integer.valueOf(yesCode1), Integer.valueOf(nowCode),
//                    Integer.valueOf(yesNextCode1), Integer.valueOf(yesNextCode2), num, i);
//            warn3(Integer.valueOf(yesCode1), Integer.valueOf(nowCode), date1, date2, num, i, 1, 1000012);
//            warn3(Integer.valueOf(yesCode1), Integer.valueOf(nowCode), date1, date2, num, i, 2, 1000005);
//            warn3(Integer.valueOf(yesCode1), Integer.valueOf(nowCode), date1, date2, num, i, 3, 1000007);
        }
        getYiLou(num);
    }

    public void warn(Integer yesCode1, Integer yesCode2, Integer nowCode, String num, Integer weizhi) {
        long day = DateUtil.between(DATE_INIT, new Date(), DateUnit.DAY, true);
        long issue = ISSUE + day * 288;
//        if (nowCode - yesCode == 1) {
//            String msg = StrUtil.format("{},位置:{},间隔1,昨日:{},今日:{}", issue + Integer.valueOf(num) - 1, weizhi + 1, yesCode, nowCode);
//            send(1000005, msg);
//        }
//        if (nowCode - yesCode == 2) {
//            String msg = StrUtil.format("{},位置:{},间隔2,昨日:{},今日:{}", issue + Integer.valueOf(num) - 1, weizhi + 1, yesCode, nowCode);
//            send(1000007, msg);
//        }
        if (nowCode - yesCode1 == 0) {
            String msg = StrUtil.format("{},位置:{},间隔0,昨日:{},今日:{}", issue + Integer.valueOf(num) - 1,
                    weizhi + 1, yesCode1, nowCode);
            log.info(msg);
            send(1000006, msg);
        }
        if (nowCode - yesCode1 == 0 && nowCode - yesCode2 == 0) {
            String msg = StrUtil.format("{},位置:{},间隔0,昨日:{},前日:{},今日:{}", issue + Integer.valueOf(num) - 1,
                    weizhi + 1, yesCode1, yesCode2, nowCode);
            log.info(msg);
            send(1000009, msg);
        }
    }

    public void warn2(Integer yesCode1, Integer nowCode, Integer yesNextCode1,
                      Integer yesNextCode2, String num, Integer weizhi) {
        long day = DateUtil.between(DATE_INIT, new Date(), DateUnit.DAY, true);
        long issue = ISSUE + day * 288;

        if (nowCode - yesCode1 == 0 && yesNextCode1 - yesNextCode2 == 0) {
            String msg = StrUtil.format("{},位置:{},今日、昨日间隔0,昨日:{},今日:{},昨日+1:{},前日+1:{}", issue + Integer.valueOf(num) - 1,
                    weizhi + 1, yesCode1, nowCode, yesNextCode1, yesNextCode2);
            log.info(msg);
            send(1000012, msg);
        }
    }

    public void warn3(Integer yesCode1, Integer nowCode, String date1, String date2, String num,
                      Integer weizhi, Integer jiange, Integer appid) {
        Integer yesNextCode1 = Integer.valueOf(TABLE.get(date1 + "-" + weizhi, Integer.valueOf(num) + jiange + "").toString());
        Integer yesNextCode2 = Integer.valueOf(TABLE.get(date2 + "-" + weizhi, Integer.valueOf(num) + jiange + "").toString());

        long day = DateUtil.between(DATE_INIT, new Date(), DateUnit.DAY, true);
        long issue = ISSUE + day * 288;

        if (nowCode - yesCode1 == 0 && yesNextCode1 - yesNextCode2 == 0) {
            String msg = StrUtil.format("{},位置:{},今日、昨日间隔0,昨日:{},今日:{},昨日+{}:{},前日+{}:{}", issue + Integer.valueOf(num) - 1,
                    weizhi + 1, yesCode1, nowCode, jiange, jiange, yesNextCode1, yesNextCode2);
            log.info(msg);
            send(appid, msg);
        }
    }

    public void warn4(Long issue, Integer weizhi, String num, String oldCode, String newCode, Integer appid) {
        String msg = StrUtil.format("{},位置:{},旧最大:{},现最大:{}", issue + Integer.valueOf(num) - 1,
                weizhi, oldCode, newCode);
        log.info(msg);
        send(appid, msg);
    }

    @SneakyThrows
    public void send(Integer appid, String warnMsg) {
        WeChatMsgSend swx = new WeChatMsgSend();
        String postdata = swx.createpostdata("13459446228", "text", appid, "content", warnMsg);
        swx.post("utf-8", WeChatMsgSend.CONTENT_TYPE, (new WeChatUrlData()).getSendMessage_Url(), postdata, commonService.getWechatToken(appid));
    }

    private final static String url = "https://api.apiose122.com/klsf/getHistoryLotteryInfo.do?date={}&lotCode=10011";

    public static JSONObject readRace(String date) {

        String data = HttpUtil.createGet(StrUtil.format(url, date))
                .header(Header.USER_AGENT, AGENT)
                .header(Header.ACCEPT, ACCEPT)
                .execute().body();
        JSONObject jsonObject = JSONObject.parseObject(data);
        return jsonObject;
    }

    public static HashBasedTable<String, String, StringBuffer> getCodes(String beginDate, int num) {
        DateTime date = DateUtil.parse(beginDate);
        String format = "yyyy-MM-dd";
        List<String> dates = Lists.newArrayList();
        HashBasedTable<String, String, StringBuffer> table = HashBasedTable.create();
        for (int i = 0; i < num; i++) {
            String dateStr = DateUtil.format(DateUtil.offsetDay(date, i), format);
            dates.add(dateStr);
            System.out.println(dateStr);
            JSONObject jsonObject = readRace(dateStr);
            jisuan(jsonObject, table, dateStr);
        }
        return table;
    }

    public static void jisuan(JSONObject jsonObject, HashBasedTable<String, String, StringBuffer> table, String dateStr) {
        JSONArray datas = jsonObject.getJSONObject("result").getJSONArray("data");
        int ii = 1;
        for (int i = datas.size() - 1; i >= 0; i--) {
            JSONObject data = datas.getJSONObject(i);
            String code = data.getString("preDrawCode");
            String[] codes = code.split(",");
            ii++;
            for (int j = 0; j < codes.length; j++) {
                StringBuffer sb = table.get(String.valueOf(j), String.valueOf(ii));
                if (sb == null) {
                    sb = new StringBuffer();
                }
                sb.append(codes[j]);
                table.put(dateStr + "-" + j, String.valueOf(ii - 1), sb);
            }
        }
    }


    public void getYiLou(String num) {

        long day = DateUtil.between(DATE_INIT, new Date(), DateUnit.DAY, true);
        long issue = ISSUE + day * 288;

        String url2 = "https://api.apiose122.com/klsf/queryToDayNumberLawOfStatistics.do?lotCode=10011";
        JSONObject res = JSONObject.parseObject(HttpUtil.createGet(url2)
                .header(Header.USER_AGENT, AGENT)
                .header(Header.ACCEPT, ACCEPT)
                .execute().body());

        Map<String, String> subMap = Maps.newHashMap();

        JSONArray datas = res.getJSONObject("result").getJSONArray("data");
        for (int i = 0; i < datas.size(); i++) {
            JSONObject data = datas.getJSONObject(i);
            JSONArray lists = data.getJSONArray("list");
            String code = data.getString("code");
            for (int j = 0; j < lists.size(); j++) {
                JSONObject list = lists.getJSONObject(j);
                String rank = list.getString("rank");
                Integer missing = Math.abs(list.getInteger("missing"));
                String val = subMap.get(rank);
                if (val == null) {
                    subMap.put(rank, StrUtil.format("{}|{}", code, missing));
                } else {
                    String[] vals = val.split("\\|");
                    String codeMax = vals[0];
                    Integer max = Integer.valueOf(vals[1]);
                    String newCode = StrUtil.format("{}|{}", code, missing);
                    if (missing > max) {
                        subMap.put(rank, newCode);
                    }
                }
            }
        }
        if (FLAG == 1) {
            YI_LOU_COUNT.putAll(subMap);
        } else {
            Iterator<String> iterator = subMap.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                String val = subMap.get(key);

                String val2 = YI_LOU_COUNT.get(key);

                if (!Objects.equals(val.split("\\|")[0], val2.split("\\|")[0])) {
                    YI_LOU_COUNT.put(key, val);
                    warn4(issue, Integer.valueOf(key), num, val2, val, 1000012);
                } else {
                    String[] vals = val2.split("\\|");
                    String val3 = StrUtil.format("{}|{}", vals[0], Integer.valueOf(vals[1]) + 1);
                    YI_LOU_COUNT.put(key, val3);
                }
            }
        }
        System.out.println(YI_LOU_COUNT);
        FLAG++;
    }
}

